﻿using Microsoft.Extensions.Options;
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Repositories;

namespace Loong.Admin.Users
{
    public class UserValidator : IUserValidator
    {
        private readonly UserOptions _options;
        private readonly IRepository<User, Guid> _repository;

        public UserValidator(IOptions<UserOptions> optionsAccessor, IRepository<User, Guid> repository)
        {
            _options = optionsAccessor.Value;
            _repository = repository;
        }

        public async Task ValidateAsync(User user)
        {
            Check.NotNull(user, nameof(user));

            await ValidateUserNameAsync(user);

            if (_options.RequireUniqueEmail)
            {
                await ValidateEmailAsync(user);
            }
        }

        private async Task ValidateUserNameAsync(User user)
        {
            var userName = user.UserName;
            if (string.IsNullOrWhiteSpace(userName))
            {
                throw new BusinessException(message: "用户名不能为空");
            }
            else if (!string.IsNullOrEmpty(_options.AllowedUserNameCharacters) &&
                userName.Any(c => !_options.AllowedUserNameCharacters.Contains(c)))
            {
                throw new BusinessException(message: "用户名包含无效字符");
            }
            else
            {
                var owner = await _repository.GetAsync(o => o.NormalizedUserName == userName.ToUpperInvariant());
                if (owner != null && owner.Id != user.Id)
                {
                    throw new BusinessException(message: "用户名已经存在");
                }
            }
        }

        private async Task ValidateEmailAsync(User user)
        {
            var email = user.Email;
            if (string.IsNullOrWhiteSpace(email))
            {
                throw new BusinessException(message: "电子邮箱不能为空");
            }

            if (!new EmailAddressAttribute().IsValid(email))
            {
                throw new BusinessException(message: "电子邮箱格式不正确");
            }

            var owner = await _repository.GetAsync(o => o.NormalizedEmail == email.ToUpperInvariant());
            if (owner != null && owner.Id != user.Id)
            {
                throw new BusinessException(message: "电子邮箱已经存在");
            }
        }
    }
}
